﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FEM.Result;
using PGMHelper;

namespace PBSD_Development
{
    /// <summary>
    /// 弹塑性分析结果
    /// </summary>
    public class FEMResultObj
    {
        /// <summary>
        /// 弹塑性分析结果
        /// </summary>
        private FEMResult result { set; get; }

        /// <summary>
        /// 宏观分析结果是否可用
        /// </summary>
        private bool isGlobalEnable { set; get; }

        /// <summary>
        /// 是否有构件分析结果
        /// </summary>
        private bool isElmentEnable { set; get; }

        /// <summary>
        /// 节点管理器
        /// </summary>
        public NodeSet NodeManager { set; get; }

        /// <summary>
        /// YJK模态信息
        /// </summary>
        private ModeSet YJKModeSet { set; get; }

        /// <summary>
        /// 宏观分析结果反序列成功
        /// </summary>
        public bool isGlobalSuccess
        {
            get
            {
                return this.isGlobalEnable;
            }
        }

        /// <summary>
        /// 模型路径
        /// </summary>
        private string directPath
        {
            get
            {
                return this.result.DirectPath;
            }
        }

        #region GetMethod

        /// <summary>
        /// 地震工况列表
        /// </summary>
        /// <returns> 工况对象列表 </returns>
        public List<LoadCaseObj> GetGroundMotionLoadCaseList()
        {
            return new LoadCaseSeries(this.result).GetGroundMotionLoadCaseList();
        }

        /// <summary>
        /// 单元组对象列表
        /// </summary>
        /// <param name="groupSet"> 单元组对象 </param>
        /// <returns> 是否存在构件分析结果 </returns>
        public bool GetElementGroupSetObj(out ElementGroupSetObj groupSet)
        {
            //初始化
            groupSet = new ElementGroupSetObj();
            //存在单元分析结果
            if (!this.isElmentEnable && !this.SetElementResult())
            {
                MessageBoxExtern.Error("不存在构件分析结果！");
                return false;
            }
            //构件分析结果存在
            groupSet = new ElementGroupSetObj(this.result);
            return true;
        }

        /// <summary>
        /// 获得体系（多塔塔楼集合）
        /// </summary>
        /// <returns> 体系对象 </returns>
        public SystemObj GetSystem()
        {
            return new SystemObj(this.result);
        }

        /// <summary>
        /// 获得体系第一塔楼
        /// </summary>
        /// <returns> 塔楼对象 </returns>
        public TowerObj GetFirstTower()
        {
            return this.GetSystem().GetFirstTower();
        }

        /// <summary>
        /// 最大包围框的X向长度
        /// </summary>
        /// <returns></returns>
        public double BoundaryXLength()
        {
            return this.NodeManager.BoundaryXLength();
        }

        /// <summary>
        /// 最大包围框的Y向长度
        /// </summary>
        /// <returns></returns>
        public double BoundaryYLength()
        {
            return this.NodeManager.BoundaryYLength();
        }

        /// <summary>
        /// 最大包围框的Z向长度
        /// </summary>
        /// <returns></returns>
        public double BoundaryZLength()
        {
            return this.NodeManager.BoundaryZLength();
        }

        /// <summary>
        /// 获得YJK周期
        /// </summary>
        /// <param name="id"> 周期编号 </param>
        /// <returns></returns>
        public double GetYJKPeriod(int id)
        {
            //是否存在模态
            if (this.YJKModeSet.Count == 0) this.YJKModeSet = new ModeSet(this.result);
            return this.YJKModeSet.GetPeriod(id);
        }

        #endregion

        /// <summary>
        /// 反序列化构件分析结果
        /// </summary>
        /// <returns> 是否成功 </returns>
        public bool SetElementResult()
        {
            //宏观结果不可用
            if (!this.isGlobalEnable)
                return MessageBoxExtern.Error("宏观分析结果构造失败！");
            //所有工况改为未读
            this.result.LoadCases.PlasticGMLoadCases.ForEach(loadCase => loadCase.isComponentRead = false);
            //获得工况列表
            var readLoadCaseList = this.result.LoadCases.PlasticGMLoadCases;
            //确定要读取的工况
            FEMResult.RemoveReadLoadCase(this.result.DirectPath, readLoadCaseList);
            //读取
            if (!this.result.ReadElementReaction(readLoadCaseList, FEMReadParam.ThreadNumber)) return false;
            //反序列化
            this.isElmentEnable = this.result.GetElementsInFile(this.result.LoadCases.PlasticGMLoadCases);
            return this.isElmentEnable;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        private FEMResultObj()
        {
            //读取配置
            FEMReadParam.SetIniValue();
            //初始化
            this.result = new FEMResult();
            this.YJKModeSet = new ModeSet();
        }

        /// <summary>
        /// 构造分析结果
        /// </summary>
        /// <param name="directPath"> PF3DS所在路径或.tcl所在路径 </param>
        /// <param name="isReRead"> 如果宏观分析结果存在，是否重新读取 </param>
        public FEMResultObj(string directPath, bool isReRead):this()
        {
            //判断路径是合规
            if (!FEMResult.isDirectCorrect(directPath))
                return;
            //获得结果文件夹
            var path = FEMResult.GetGlobalDirect(directPath);
            //结果存在
            if(path != string.Empty)
            {
                //重新读取
                if(isReRead)
                {
                    //结果不存在 读取结果
                    if (!this.result.SetGlobalResult(directPath, true, false, false))
                        return;
                }
                //读取宏观分析结果
                else if (!this.result.SetObjectFromFile(directPath, path, false)) return;
            }
            else
            {
                //结果不存在 读取结果
                if (!this.result.SetGlobalResult(directPath, true, false, false))
                    return;
            }
            //方法
            this.result.initialElementInfo();
            //构造所有节点
            this.NodeManager = new NodeSet(this.result);
            //var mode = this.result.GlobalResult.Modes;
            //有效
            this.isGlobalEnable = true;
        }
    }
}
